/**
 * 
 */
package org.dragonfire.util;

import java.util.ArrayList;
import java.util.Stack;

import com.stevesoft.pat.Regex;

public class DString {

	public static String cycleLeft(String string, int chars) {
		for (int i = 0; i < chars; i++) {
			string = string.substring(1) + string.charAt(0);
		}
		return string;
	}

	public static String cycleRight(String string, int chars) {
		for (int i = 0; i < chars; i++) {
			string = string.charAt(string.length() - 1) + string.substring(0, string.length() - 1);
		}
		return string;
	}

	public static String[] splitTopLevel(String line, char split) {
		if (line == null)
			line = "";
		if (line.length() == 0)
			return new String[0];
		ArrayList<String> lines = new ArrayList<String>();
		int start = 0;
		int level = 0;
		boolean inQuotes = false;
		for (int i = 0; i < line.length(); i++) {
			char c = line.charAt(i);
			if (c == '\\' && inQuotes) {
				i++; // skip next char because it's escaped
				continue;
			}
			if (level == 0 && i > start && c == split && !inQuotes) {
				lines.add(line.substring(start, i));
				start = i + 1;
			}
			if (("{[(").indexOf(c) > -1 && !inQuotes)
				level++;
			if (c == '"' && (c == 0 || !inQuotes || (line.charAt(i - 1) != '\\')))
				inQuotes = !inQuotes;
			if (("}])").indexOf(c) > -1 && !inQuotes)
				level--;
		}
		if (start < line.length())
			lines.add(line.substring(start, line.length()));
		return lines.toArray(new String[lines.size()]);
	}

	public static String trim(String line) {
		while (line.length() > 0 && line.charAt(0) == ' ')
			line = line.substring(1);
		while (line.length() > 0 && line.charAt(line.length() - 1) == ' ')
			line = line.substring(0, line.length() - 1);
		return line.replaceAll("^\\s*(\\S.*\\S)\\s*", "$1");
	}

	public static String[] trim(String[] lines) {
		for (int i = 0; i < lines.length; i++) {
			lines[i] = trim(lines[i]);
		}
		return lines;
	}

	public static boolean checkBrackets(String str) {
		Stack<Character> close = new Stack<Character>();
		String opens = "<({[";
		String closes = ">)}]";
		for (int i = 0; i < str.length(); i++) {
			if (opens.contains(str.charAt(i) + "")) {
				close.push(closes.substring(opens.indexOf(str.charAt(i)), opens.indexOf(str.charAt(i)) + 1).charAt(0));
			}
			else if (closes.contains(str.charAt(i) + "")) {
				if (close.isEmpty())
					return false;
				if (str.charAt(i) != close.pop())
					return false;
			}
		}
		return close.isEmpty();
	}

	public static String tokens(String string, int start, int end, char token) {
		String[] parts = string.split("\\" + token);
		if (start > parts.length)
			start = parts.length;
		if (end > parts.length || end < 0)
			end = parts.length;
		start -= 1;
		end -= 1;
		if (start < 0 || end < start || end < 0)
			throw new IllegalArgumentException("Illegal token index");
		String out = "";
		for (int i = start; i <= end; i++) {
			out += parts[i];
			if (i < end)
				out += token;
		}
		return out;
	}

	public static String collapseSpaces(String text) {
		return Regex.replaceAll(text, "(?Q)\\s+", " ");
	}

	public static String join(String[] array, int start, int end, String sep) {
		String output = "";
		for (int i = start; i <= end; i++) {
			if (i > start)
				output += sep;
			output += array[i];
		}
		return output;
	}

	public static String join(String[] array, String sep) {
		return join(array, 0, array.length - 1, sep);
	}

	public static String extractString(String text) {
		// validate params
		if (text == null)
			throw new IllegalArgumentException("Text may not be null.");
		if (!text.matches("(?s)\\\".*\\\""))
			throw new IllegalArgumentException("Text is not a parser string.");
		// remove quotes
		text = text.substring(1, text.length() - 1);
		// parse special escape chars
		String output = "";
		for (int i = 0; i < text.length(); i++) {
			char c = text.charAt(i);
			if (c == '\\') {
				if (i + 1 == text.length())
					throw new IllegalArgumentException("The last character may not be an unescaped backslash");
				i++;
				c = text.charAt(i);
				if (c == 'r')
					c = 0xD;
				if (c == 'n')
					c = 0xA;
				if (c == 't')
					c = 0x9;
			}
			output += c;
		}
		/*
		 * text = text.replaceAll("\\\\n", "\n").replaceAll("\\\\t",
		 * "\t").replaceAll("\\\\r", "\r"); // remove escape chars text =
		 * text.replaceAll("\\\\(.)", "$1");
		 */
		return output;
	}
}